/**
 * 网络数据请求获取封装
 * */
import 'package:demo_flutter/library.dart';
import 'package:dio/dio.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'package:shared_preferences/shared_preferences.dart';

class DioUtils {
  factory DioUtils() => _getInstance();

  static final String BASE_URL = '';
  static const int CONNECT_TIMEOUT = 10000;
  static const int RECEIVE_TIMEOUT = 3000;

  /// http request methods
  static const String GET = 'get';
  static const String POST = 'post';

  static get dioInstance => _getInstance();

  static DioUtils _instance;

  Dio _dio;

  DioUtils._internal() {
    BaseOptions baseOptions = BaseOptions(
      baseUrl: BASE_URL,
      connectTimeout: CONNECT_TIMEOUT,
      receiveTimeout: RECEIVE_TIMEOUT,
      responseType: ResponseType.json,
    );
    // 添加测试版本代码，不会被打包到release当中去
    assert(() {
      baseOptions.baseUrl = "";
    }());
    Dio dio = new Dio();
    dio.interceptors.add(RequestInterceptor(dio));
    // debug 模式下面添加网络请求日志输出
    assert(() {
      dio.interceptors.add(
        PrettyDioLogger(
          requestHeader: true,
          requestBody: true,
          responseBody: true,
          responseHeader: false,
          error: true,
          compact: true,
          maxWidth: 90,),
      );
    }());
    // 保存实例
    this._dio = dio;
  }

  static DioUtils _getInstance() {
    if (_instance == null) {
      _instance = new DioUtils._internal();
    }
    return _instance;
  }

  Future getRequest({@required String uri, Map<String, dynamic> params}){
    return this._dio.get(uri, queryParameters: params);
  }

  Future postRequest({@required String uri, Map<String, dynamic> params}){
    return this._dio.post(uri, data: params);
  }

  Future request(
      {@required String uri,
        @required String type,
        Map<String, dynamic> params}){
    assert(type != GET || type != POST,
    'you must set the type of [DioUtils.GET] or [DioUtils.POST]');
    return type == GET
        ? this.getRequest(uri: uri, params: params)
        : this.postRequest(uri: uri, params: params);
  }

  clear() {}
}

class RequestInterceptor extends Interceptor {
  Dio dio;

  RequestInterceptor(this.dio);

  @override
  Future onRequest(RequestOptions options) async {
    // TODO: implement onRequest
    super.onRequest(options);
    dio.lock();
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String token = prefs.getString("loginToken");
    options.headers["Authorization"] = token;
    dio.unlock();
    return options;
  }

  @override
  Future onResponse(Response response) {
    // TODO: implement onResponse
    super.onResponse(response);
    if(response.statusCode == 200) {
      dio.resolve(response.data ?? response);
    }
  }

  @override
  Future onError(DioError err) {
    // TODO: implement onError
    super.onError(err);
    dio.reject(err);
//    return super.onError(err);
  }
}
